package com.csi.service.impl;

import com.csi.dao.EmployeeDao;
import com.csi.dao.UserDao;
import com.csi.dao.impl.EmployeeDaoImpl;
import com.csi.dao.impl.UserDaoImpl;
import com.csi.domain.*;
import com.csi.pojo.PageBean;
import com.csi.service.UserService;
import com.csi.utils.MD5Tools;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;

public class UserServiceImpl implements UserService {
    @Override
    public User login(String loginAccount, String loginPassword) {
        UserDao userDao = new UserDaoImpl();

        User user = null;
        try {
            //根据账号获取对应的盐值
            String salt = userDao.findSalt(loginAccount);

            //将用户的密码和盐值叠加生成的新密码
            //但是用户输入的时候密码还是他认为的密码比如123456但是实际数据库中存储的是被MD5加密后的密码
            loginPassword = MD5Tools.MD5Encode(loginPassword + salt, "utf-8");

            user = userDao.login(loginAccount, loginPassword);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return user;
    }

    @Override
    public List<User> findAll() {
        UserDao userDao = new UserDaoImpl();

        List<User> users = null;
        try {
            users = userDao.findAll();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return users;
    }

    @Override
    public PageBean<User> findPage(int currentPageNumber) {

        UserDao userDao = new UserDaoImpl();

        PageBean<User> page = null;
        try {
            page = userDao.findPage(currentPageNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return page;
    }

    @Override
    public User findById(int userId) {

        UserDao userDao = new UserDaoImpl();

        User user = null;
        try {
            user = userDao.findById(userId);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return user;
    }

    @Override
    public void updateStatus(int status,int userId) {
        UserDao userDao = new UserDaoImpl();

        try {
            userDao.updateStatus(status,userId);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public User updatePassword(int userId,String password) {

        UserDao userDao = new UserDaoImpl();
        User user = null;
        try {
            user = userDao.updatePassword(userId,password);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return user;
    }

    @Override
    public void updateInfo(User user) {
        UserDao userDao = new UserDaoImpl();

        try {
            userDao.updateInfo(user);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String findSalt(int userId) {

        UserDao userDao = new UserDaoImpl();
        String salt = null;
        try {
            salt = userDao.findSalt(userId);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return salt;
    }

    @Override
    public User findByLoginAccount(String loginAccount) {
        UserDao userDao = new UserDaoImpl();

        User user = null;
        try {
            user = userDao.findByLoginAccount(loginAccount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return user;
    }

    @Override
    public void entry(Integer userId, List<Integer> roles) {
        UserDao userDao = new UserDaoImpl();

        EmployeeDao employeeDao = new EmployeeDaoImpl();
        Employee employee = new Employee();

        String lastEmployeeId = null; // 最后的员工编号
        try {
            lastEmployeeId = employeeDao.findLast();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        String substring = lastEmployeeId.substring(1, 7);
        int i = Integer.valueOf(substring) + 1;
        employee.setEmployeeAccount("E" + i);

        try {
            userDao.entry(userId,employee,roles);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void uploadPath(String imageAddress, int userId) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.uploadPath(imageAddress, userId);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public BindAccount queryBindAccount(String userNumber, String accountNumber) {

        UserDao userDao = new UserDaoImpl();

        BindAccount bindaccount = null;
        try {
            bindaccount = userDao.queryBindAccount(userNumber, accountNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return bindaccount;
    }

    @Override
    public HashMap<String, Object> queryInfo(String userNumber, String accountNumber) {

        UserDao userDao = new UserDaoImpl();

        HashMap<String, Object> info = null;
        try {
            info = userDao.queryInfo(userNumber, accountNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return info;
    }

    @Override
    public double queryBalance(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        double balance = 0.00;

        try {
            balance = userDao.queryBalance(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return balance;
    }

    @Override
    public double queryPayLimit(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        double payLimit = 0.00;

        try {
            payLimit = userDao.queryPayLimit(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return payLimit;

    }

    @Override
    public List<AccountDetails> queryAccountList(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        List<AccountDetails> accountDetailsList = null;

        try {
            accountDetailsList = userDao.queryAccountList(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return accountDetailsList;

    }

    @Override
    public List<AccountCredDetails> queryCredAccountList(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        List<AccountCredDetails> accountCredDetailsList = null;

        try {
            accountCredDetailsList = userDao.queryCredAccountList(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return accountCredDetailsList;

    }

    @Override
    public List<BindAccount> queryBindAccountList(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        List<BindAccount> bindBindAccountList = null;

        try {
            bindBindAccountList = userDao.queryBindAccountList(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return bindBindAccountList;
    }

    @Override
    public void transferByWallet(String userNumber, String targetUserNumber, double transferAmount) {
        UserDao userDao =  new UserDaoImpl();

        try {
            userDao.transferByWallet(userNumber,targetUserNumber,transferAmount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String queryPayPassword(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        String payPassword = null;

        try {
            payPassword = userDao.queryPayPassword(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return payPassword;

    }

    @Override
    public boolean checkPayPassword(String userNumber, String payPassword, int userId) {

        UserDao userDao = new UserDaoImpl();

        try {
            String realPayPassword = userDao.queryPayPassword(userNumber);
            int count = 0;
            while (!payPassword.equals(realPayPassword) && count < 3) {
                count++;
                if (count == 3) {
                    userDao.updateStatus(0,userId);
                    return false;
                }
            }
            return true;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void updatePayPassword(String userNumber, String password) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.updatePayPassword(userNumber, password);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void updatePayLimit(String userNumber, Double payLimit) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.updatePayLimit(userNumber, payLimit);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void payByWallet(String userNumber, String targetAccountNumber, double amount) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.payByWallet(userNumber, targetAccountNumber, amount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void payByAccount(String accountNumber, String targetUserNumber, double amount) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.payByAccount(accountNumber, targetUserNumber, amount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void payByCredAccount(String accountNumber, String targetUserNumber, double amount) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.payByCredAccount(accountNumber, targetUserNumber, amount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public AccountCredDetails queryAccountCredDetails(String userNumber, String accountNumber) {
        UserDao userDao = new UserDaoImpl();

        AccountCredDetails accountCredDetails = null;
        try {
            accountCredDetails = userDao.queryAccountCredDetails(userNumber, accountNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return accountCredDetails;
    }

    public double queryAvailableBalance(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        double availableBalance = 0;

        try {
            availableBalance = userDao.queryAvailableBalance(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return availableBalance;
    }

    @Override
    public double queryAvailableLimit(String userNumber) {

        UserDao userDao = new UserDaoImpl();

        double availableLimit = 0;

        try {
            availableLimit = userDao.queryAvailableLimit(userNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return availableLimit;
    }

    @Override
    public void bindCard(String userNumber, String accountNumber, String accountType) {
        UserDao userDao = new UserDaoImpl();

        try {
            userDao.bindCard(userNumber,accountNumber,accountType);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void unbindCard(String userNumber, String accountNumber) {
        UserDao userDao = new UserDaoImpl();

        try {
            userDao.unbindCard(userNumber,accountNumber);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Integer register(User user) throws SQLException {
        UserDao userDao = new UserDaoImpl();

        String lastUserId = null; // 最后的编号
        try {
            lastUserId = userDao.findLast();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        long j = Long.valueOf(lastUserId.substring(1, 12)) + 1;
        user.setUserNumber("U" + j);

        // 生成随机盐
        String salt = MD5Tools.getSalt();
        // 对密码进行加盐和加密
        String encryptedPassword = MD5Tools.MD5Encode(user.getLoginPassword() + salt, "utf-8");

        user.setLoginPassword(encryptedPassword);

        Integer userId = 0;
        try {
            userId = userDao.register(user, salt);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return userId;

    }

    @Override
    public void recharge(String userNumber, String accountNumber, double amount) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.recharge(userNumber, accountNumber, amount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void cashOut(String userNumber, String accountNumber, double amount) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.cashOut(userNumber, accountNumber, amount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void collectMoney(String userNumber, String targetUserNumber, double amount) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.collectMoney(userNumber, targetUserNumber, amount);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void updateAllInfo(User user) {
        UserDao userDao = new UserDaoImpl();

        try {
            userDao.updateAllInfo(user);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void forgotPassword(String phone, String loginPassword) {
        UserDao userDao = new UserDaoImpl();

        try {
            userDao.forgotPassword(phone,loginPassword);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Integer queryUserIdByPhone(String phone) {
        UserDao userDao = new UserDaoImpl();

        Integer userId = null;
        try {
            userId = userDao.queryUserIdByPhone(phone);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return userId;
    }

    @Override
    public User findUserByPhone(String phone) {

        UserDao userDao = new UserDaoImpl();

        User user = null;
        try {
            user = userDao.findUserByPhone(phone);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return user;
    }

    @Override
    public void uploadCodePath(String codePath, int userId) {

        UserDao userDao = new UserDaoImpl();

        try {
            userDao.uploadCodePath(codePath, userId);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }
}
